package engine.systems.spatial.proximity
{
	import engine.classes.enumerations.SystemPriority;
	import engine.groups.Group;
	import engine.systems.update.GameSystem;
	import engine.utils.GeomUtils;

	public class ProximitySystem extends GameSystem
	{
		private var data:ProximityData;
		private var distance:Number;
		
		public function ProximitySystem()
		{
			super(ProximityNode, updateNode);
			
			this.priority = SystemPriority.POST_MOTION;
		}
		
		public function updateNode(node:ProximityNode, time:Number):void
		{
			switch(node.proximity.type)
			{
				case Proximity.CIRCLE:
					for each(data in node.proximity.data)
					{
						distance = GeomUtils.distance(node.spatial.x, node.spatial.y, data.spatial.x, data.spatial.y);
					
						this.trigger(node, distance <= node.proximity.radius);
					}
					break;
				
				case Proximity.SQUARE:
					for each(data in node.proximity.data)
					{
						var inside:Boolean = false;
						inside = Math.abs(node.spatial.x - data.spatial.x) <= node.proximity.radius;
						inside = Math.abs(node.spatial.y - data.spatial.y) <= node.proximity.radius;
					
						this.trigger(node, inside);
					}
					break;
			}
		}
		
		private function trigger(node:ProximityNode, inside:Boolean):void
		{
			if(inside)
			{
				if(data.inside) return;
				data.inside = true;
				
				if(node.proximity.entered.numListeners > 0)
					node.proximity.entered.dispatch(data.entity);
			}
			else
			{
				if(!data.inside) return;
				data.inside = false;
				
				if(node.proximity.exited.numListeners > 0)
					node.proximity.exited.dispatch(data.entity);
			}
		}
	}
}